package com.ropa.java.consumer_demo;


import cn.hutool.core.util.RandomUtil;
import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Client;
import feign.Feign;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientBuilder;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@RestController
public class ConsumerApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class, args);
    }

    @Autowired
    private DemoFeignClient demoFeignClient;

    @GetMapping("test-info")
    public String  testInfo(){
        return "rpc: "+ demoFeignClient.info();
    }


    @GetMapping("test-url-encoded")
    public String  testUrlEncoded(){
        return "rpc: "+ demoFeignClient.urlEncoded(RandomUtil.randomString(2),
                RandomUtil.randomNumbers(3),
                RandomUtil.randomString(4));
    }

    @Bean
    public DemoFeignClient demoFeignClient(SpringClientFactory springClientFactory,
                                           CachingSpringLoadBalancerFactory loadBalancerFactory){

        Client.Default aDefault = new Client.Default(null, null);

//        LoadBalancerFeignClient loadBalancerFeignClient = new LoadBalancerFeignClient(aDefault, loadBalancerFactory, springClientFactory);

        DemoFeignClient target = Feign.builder()
                .encoder(feignEncoder())
                .decoder(feignDecoder())
                .contract(new SpringMvcContract())
                .client(aDefault)
                .target(DemoFeignClient.class, "http://lo:8888");
        return target;
    }


    @Bean
    @ConditionalOnMissingBean
    public Decoder feignDecoder() {
        return new ResponseEntityDecoder(new SpringDecoder(new ObjectFactory<HttpMessageConverters>() {
            @Override
            public HttpMessageConverters getObject() throws BeansException {
                return new HttpMessageConverters(new MappingJackson2HttpMessageConverter());
            }
        }));
    }

    @Bean
    @ConditionalOnMissingBean
    public Encoder feignEncoder() {
//        return new SpringEncoder(feignHttpMessageConverter());
        HttpMessageConverter<Object> jacksonConverter = new MappingJackson2HttpMessageConverter(new ObjectMapper());
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
        return new SpringEncoder(objectFactory);
    }

}

//@FeignClient("producer")
interface DemoFeignClient{

    @GetMapping("info")
    public String info();


    @PostMapping(value = "url-encoded",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    Map urlEncoded(@RequestParam("Mobile") String mobile,
                   @RequestParam("Content") String Content,
                   @RequestParam("CorpID") String CorpID);
}